package com.flame.shapeville.controller;

import com.flame.shapeville.bean.Course;
import com.flame.shapeville.bean.Exercise;
import com.flame.shapeville.bean.Task;
import com.flame.shapeville.bean.User;
import com.flame.shapeville.enums.SceneStyle;
import com.flame.shapeville.factory.BeanFactory;
import com.flame.shapeville.service.ExerciseService;
import com.flame.shapeville.service.TaskService;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;

import java.util.List;

/**
 * Controller class responsible for managing and displaying score information.
 * <p>
 * Handles different score contexts (course, main menu, task) and updates UI components accordingly.
 *
 * @author Flame Dev Team
 * @version 1.0
 * @since 2025-05-11
 */
public class ScoreController implements JfController {
    /**
     * Root container of the score panel.
     */
    @FXML
    private HBox root;

    /**
     * Label displaying basic exercise score.
     */
    @FXML
    private Label basicScore;

    /**
     * Label displaying advanced exercise score.
     */
    @FXML
    private Label advancedScore;

    /**
     * Label displaying total score.
     */
    @FXML
    private Label totalScore;

    /**
     * Initializes the controller based on the current scene style.
     * <p>
     * Loads appropriate score data depending on whether user is in:
     * - COURSE scene: shows course-specific scores
     * - MAIN scene: shows overall course scores
     * - TASK scene: shows current task scores
     */
    @Override
    public void init() {
        User user = (User) BeanFactory.getBean("user");
        SceneStyle curSceneStyle = SceneController.getSceneStyle();
        switch (curSceneStyle) {
            case COURSE:
                initScore(user.getId());
                break;
            case MAIN:
                initCourseScore(user.getId());
                break;
            case TASK:
                initTaskScore();
                break;
        }
    }

    /**
     * Initializes scores for all tasks of a specific user.
     *
     * @param userId ID of the user whose scores to load
     */
    private void initScore(String userId) {
        TaskService taskService = (TaskService) BeanFactory.getBean("taskService");
        List<Task> tasks = taskService.loadTask(userId);
        setScore(tasks);
    }

    /**
     * Initializes scores for tasks belonging to a specific course and user.
     *
     * @param userId ID of the user
     */
    private void initCourseScore(String userId) {
        Course course = (Course) BeanFactory.getBean("curCourse");
        TaskService taskService = (TaskService) BeanFactory.getBean("taskService");
        List<Task> tasks = taskService.loadTask(userId, course.getId());
        setScore(tasks);
    }

    /**
     * Initializes score display with the current task's pre-calculated scores.
     */
    private void initTaskScore() {
        Task task = (Task) BeanFactory.getBean("curTask");
        basicScore.setText(task.getBasicScore() + "");
        advancedScore.setText(task.getAdvancedScore() + "");
        totalScore.setText(task.getTotalScore() + "");
    }

    /**
     * Calculates and sets overall scores from a list of tasks.
     *
     * @param tasks List of Task objects containing score data
     */
    private void setScore(List<Task> tasks) {
        int basicScore = 0, advancedScore = 0, totalScore = 0;
        for (Task task : tasks) {
            basicScore += task.getBasicScore();
            advancedScore += task.getAdvancedScore();
            totalScore += task.getTotalScore();
        }
        this.basicScore.setText(basicScore + "");
        this.advancedScore.setText(advancedScore + "");
        this.totalScore.setText(totalScore + "");
    }

    /**
     * Updates the displayed score by recalculating based on current exercises.
     * <p>
     * Used when task is in progress and scores may have changed dynamically.
     */
    public void updateTaskScore() {
        Task task = (Task) BeanFactory.getBean("curTask");
        ExerciseService exerciseService = (ExerciseService) BeanFactory.getBean("exerciseService");
        List<Exercise> exercises = exerciseService.loadExercise(task.getId());
        int basicScore = 0, advancedScore = 0, totalScore = 0;
        for (Exercise exercise : exercises) {
            if (!exercise.getAdvanced()) {
                basicScore += exercise.getScore();
            } else {
                advancedScore += exercise.getScore();
            }
            totalScore += exercise.getScore();
        }
        this.basicScore.setText(basicScore + "");
        this.advancedScore.setText(advancedScore + "");
        this.totalScore.setText(totalScore + "");
    }

    /**
     * Closes the score panel by disabling and hiding it.
     */
    @FXML
    private void close() {
        root.setDisable(true);
        root.setVisible(false);
    }
}
